package com.nuoniu.sibanyun.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.config.JwtUtils;
import com.nuoniu.sibanyun.entity.SysLog;
import com.nuoniu.sibanyun.entity.SysMenu;
import com.nuoniu.sibanyun.entity.dto.SysLogDto;
import com.nuoniu.sibanyun.mapper.SysLogMapper;
import com.nuoniu.sibanyun.service.ISysLogService;
import com.nuoniu.sibanyun.service.ISysMenuService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import com.nuoniu.sibanyun.utils.IpUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.Date;
import java.util.Map;


/**
 * <p>
 * 操作日志表 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-04-23
 */
@Service
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements ISysLogService {

    @Autowired
    private SysLogMapper sysLogMapper;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private ISysMenuService sysMenuService;

    @Override
    public Page pageLogs(Page page, SysLogDto params) {
        UserInfo userInfo = UserThreadLocal.get();
        params.setCompanyId(userInfo.getCompanyId());
        params.setCompanyName(userInfo.getCompanyName());
        Page<SysLog> sysLogList = sysLogMapper.getSysLogList(params, page);
        return sysLogList;
    }

    /**
     * 保存日志
     * @author 小啊刚
     * @date 2020/6/13
     */
    public void saveLog(String userName, Long time, String title, HttpServletRequest request) {
        SysLog sysLog = new SysLog();
        UserInfo userInfo = jwtUtils.getRedisUserInfo(userName);
        //String uri = request.getRequestURI().trim();
        String host = request.getHeader("host");
        String httpMethod  =  request.getMethod();
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        //浏览器
        Browser browser = userAgent.getBrowser();
        //操作系统
        OperatingSystem os = userAgent.getOperatingSystem();
        String ipAddress = IpUtil.getClientIp(request);
//        if(httpMethod == null || httpMethod.equals("OPTIONS") || httpMethod.equals("options")) {
//            return;
//        }

        sysLog.setCompanyId(userInfo.getCompanyId());
        sysLog.setCompanyName(userInfo.getCompanyName());
        sysLog.setCreateBy(userInfo.getUserId());
        sysLog.setCreateByName(userInfo.getRealName());
        sysLog.setLogTitle(title);
        sysLog.setUserAgent(request.getHeader("User-Agent"));
        sysLog.setBrowserName(browser.getName());
        sysLog.setDeviceName(os.getName());
        sysLog.setRequestUri("login");
        sysLog.setRequestMethod(httpMethod);
        sysLog.setRequestParams(getMapToParams(request.getParameterMap()));
        sysLog.setExecuteTime(System.currentTimeMillis() - time);
        sysLog.setRemoteAddr(ipAddress);
        sysLog.setServerAddr(host);
        sysLog.setCreateDate(new Date());
        save(sysLog);
    }

    public void saveLogOut() {
        System.out.println("用户退出");
    }
    public void clean(){
        baseMapper.clean(LocalDate.now());
    }
    @Async
    public void addOperationLog(ProceedingJoinPoint joinPoint, Object res, long time,  HttpServletRequest request, UserInfo userInfo) {
        // 记录下请求内容
        try {
            String uri = request.getRequestURI().trim();
            String host = request.getHeader("host");
            String httpMethod  =  request.getMethod();
            UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
            //浏览器
            Browser browser = userAgent.getBrowser();
            //操作系统
            OperatingSystem os = userAgent.getOperatingSystem();
            String ipAddress = IpUtil.getClientIp(request);
            if(httpMethod.equals("OPTIONS") || httpMethod.equals("options")) {
                return;
            }
            // 获取url的参数
            Map<String,String[]> params = request.getParameterMap(); //请求提交的参数
            SysLog sysLog = new SysLog();
            SysMenu sysMenu = sysMenuService.getByUri(uri);
            if(sysMenu == null) {
                if(!uri.equals("/erp/voucherDesign/list") || params.get("source") == null) {
                    return;
                }

                String url = uri + "/" + params.get("source")[0];
                sysMenu = sysMenuService.getByUri(url);
                if(sysMenu == null) {
                    return;
                }
            }

            //保存日志
            sysLog.setCompanyId(userInfo.getCompanyId());
            sysLog.setCompanyName(userInfo.getCompanyName());
            sysLog.setCreateBy(userInfo.getUserId());
            sysLog.setCreateByName(userInfo.getRealName());
            sysLog.setLogTitle(sysMenu.getTreeNames());
            sysLog.setUserAgent(request.getHeader("User-Agent"));
            sysLog.setBrowserName(browser.getName());
            sysLog.setDeviceName(os.getName());
            sysLog.setRequestUri(uri);
            sysLog.setRequestMethod(httpMethod);
            sysLog.setRequestParams(getMapToParams(params));
            sysLog.setExecuteTime(time);
            sysLog.setRemoteAddr(ipAddress);
            sysLog.setServerAddr(host);
            sysLog.setCreateDate(new Date());
            this.save(sysLog);
        }catch (Exception e) {

        }
    }


    /**
     * 设置参数
     */
    public String getMapToParams(Map<String, String[]> paramMap) {
        StringBuilder params = new StringBuilder();
        for (Map.Entry<String, String[]> param : ((Map<String, String[]>)paramMap).entrySet()){
            params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "=");
            String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
            params.append(paramValue) ;
        }
        return params.toString();
    }

}
